/**
 * 
 */
package icraf.carbon.gui.chart;

import icraf.carbon.gui.MenuFactory.MenuProperty;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

class ShapeSettingPanel extends JPanel {

	public class Listener implements ActionListener, ChangeListener,
			FocusListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource().equals(lineTypeTF)) {
				updateLineFormat();
			} else if (e.getSource().equals(lineColorB)) {
				Color c = JColorChooser.showDialog(lineColorB,
						MenuProperty.CHART_SETTING_LINE_COLOR.getLabel(),
						shapeSetting.lineColor);
				shapeSetting.lineColor = c != null ? c : shapeSetting.lineColor;
				lineColorIcon.setColor(shapeSetting.lineColor);
				lineColorB.repaint();
				previewPanel.repaint();
				
			} else if (e.getSource().equals(fillColorB)) {
				Color c = JColorChooser.showDialog(fillColorB,
						MenuProperty.CHART_SETTING_FILL_COLOR.getLabel(),
						shapeSetting.fillColor);
				shapeSetting.fillColor = c != null ? c : shapeSetting.fillColor;
				fillColorIcon.setColor(shapeSetting.fillColor);
				fillColorB.repaint();
				previewPanel.repaint();
				
			}
			toggleListener(null);

		}

		@Override
		public void focusGained(FocusEvent arg0) {
		}

		@Override
		public void focusLost(FocusEvent e) {
			if (e.getSource().equals(lineTypeTF)) {
				updateLineFormat();
				toggleListener(null);
			}
		}

		@Override
		public void stateChanged(ChangeEvent e) {
			if (e.getSource().equals(lineSizeTF)) {
				shapeSetting.lineSize = ((Number) lineSizeTF.getValue()).floatValue();
				previewPanel.repaint();
			} else if (e.getSource().equals(cornerTF)) {
				shapeSetting.corner = ((Number) cornerTF.getValue()).floatValue();
				previewPanel.repaint();
			}
			toggleListener(null);
		}

		private void updateLineFormat() {
			if (lineTypeTF.getText().equalsIgnoreCase("")) {
				shapeSetting.dashPattern = null;
				previewPanel.repaint();
				return;
			}
			String[] strv = lineTypeTF.getText().split(";");
			float vList[] = new float[strv.length];
			int i = 0;
			try {
				for (String s : strv) {
					Float v;
					v = formatter.parse(s).floatValue();
					if ((v != null) && (v >= 0)) {
						vList[i] = v;
						i++;
					}
				}
				shapeSetting.dashPattern = vList;
				previewPanel.repaint();
			} catch (Exception e1) {
				updateDashField();
			}
		}

	}



	public static final int LINE_SETTING = 1, SHAPE_SETTING = 2, SHAPE_REC_SETTING = 3, COLOR_SETTING = 4;
	private static final long serialVersionUID = -4339756690912887507L;
	private JSpinner cornerTF;
	private JButton fillColorB;
	private ColorIcon fillColorIcon;
	
	private JButton lineColorB;
	private ColorIcon lineColorIcon;
	private JSpinner lineSizeTF;
	private JTextField lineTypeTF;
	private Listener listener = new Listener();
	private ShapePreviewPanel previewPanel= new ShapePreviewPanel();

	private ShapeFormat shapeSetting = new ShapeFormat();
	private DecimalFormat formatter = (DecimalFormat) NumberFormat
			.getNumberInstance();
	
	public ShapeSettingPanel(int settingType) {
		previewPanel.setSettingType(settingType);
		previewPanel.setShapeSetting(shapeSetting);
		setLayout(new BorderLayout());

		JPanel p = new JPanel();
		p.setLayout(new BorderLayout());
		p.setBorder(BorderFactory.createTitledBorder(BorderFactory
				.createCompoundBorder(BorderFactory
						.createLineBorder(Color.lightGray), BorderFactory
						.createEmptyBorder(0, 5, 5, 5)),
				MenuProperty.CHART_SETTING_PREVIEW.getLabel()));
		p.add(previewPanel);
		add(p);

		JLabel l1 = new JLabel(MenuProperty.CHART_SETTING_LINE_SIZE.getLabel()
				+ ":");
		JLabel l2 = new JLabel(MenuProperty.CHART_SETTING_LINE_TYPE.getLabel()
				+ ":");
		JLabel l3 = new JLabel(MenuProperty.CHART_SETTING_LINE_COLOR.getLabel()
				+ ":");
		JLabel l4 = new JLabel(MenuProperty.CHART_SETTING_FILL_COLOR.getLabel()
				+ ":");
		JLabel l5 = new JLabel(MenuProperty.CHART_SETTING_CORNER.getLabel()
				+ ":");
		if (settingType == SHAPE_SETTING || settingType == SHAPE_REC_SETTING || settingType == LINE_SETTING) {
			SpinnerModel model = new SpinnerNumberModel(shapeSetting.lineSize, 0, 100, 1);
			lineSizeTF = new JSpinner(model);
			lineSizeTF.setEditor(new JSpinner.NumberEditor(lineSizeTF, "#"));
			lineSizeTF.addChangeListener(listener);
	
			lineTypeTF = new JTextField(8);
			lineTypeTF.addActionListener(listener);
			lineTypeTF.addFocusListener(listener);
	
			lineColorB = new JButton();
			lineColorB.addActionListener(listener);
			lineColorIcon = new ColorIcon(shapeSetting.lineColor, 40, 15);
			lineColorB.setIcon(lineColorIcon);
		}
		if (settingType == SHAPE_SETTING || settingType == SHAPE_REC_SETTING || settingType == COLOR_SETTING) {
			fillColorB = new JButton();
			fillColorB.addActionListener(listener);
			fillColorIcon = new ColorIcon(shapeSetting.fillColor, 40, 15);
			fillColorB.setIcon(fillColorIcon);
			if (settingType == SHAPE_SETTING) {
				SpinnerModel modelC = new SpinnerNumberModel(shapeSetting.corner, 0, 300, 1);
				cornerTF = new JSpinner(modelC);
				cornerTF.setEditor(new JSpinner.NumberEditor(cornerTF, "#"));
				cornerTF.addChangeListener(listener);
			}
		}
		JPanel controlP = new JPanel();
		controlP.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));
		controlP.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();

		c.insets = new Insets(2, 2, 2, 2);
		c.anchor = GridBagConstraints.WEST;
		c.fill = GridBagConstraints.BOTH;
		if (settingType == SHAPE_SETTING || settingType == SHAPE_REC_SETTING || settingType == LINE_SETTING) {
			c.gridx = 0;
			c.gridy = 0;
			controlP.add(l1, c);
			c.gridx = 1;
			controlP.add(lineSizeTF, c);
			c.gridx = 0;
			c.gridy = 1;
			controlP.add(l2, c);
			c.gridx = 1;
			controlP.add(lineTypeTF, c);
			c.gridx = 0;
			c.gridy = 2;
			controlP.add(l3, c);
			c.gridx = 1;
			controlP.add(lineColorB, c);
		}
		if (settingType == SHAPE_SETTING || settingType == SHAPE_REC_SETTING || settingType == COLOR_SETTING) {
			c.gridx = 0;
			c.gridy = 3;
			controlP.add(l4, c);
			c.gridx = 1;
			controlP.add(fillColorB, c);
			if (settingType == SHAPE_SETTING) {
				c.gridx = 0;
				c.gridy = 4;
				controlP.add(l5, c);
				c.gridx = 1;
				controlP.add(cornerTF, c);
			}
		}
		add(controlP, BorderLayout.NORTH);
	}

	public LineFormat getSetting(LineFormat ls) {
		ls.lineColor = shapeSetting.lineColor;
		ls.lineSize = shapeSetting.lineSize;
		ls.dashPattern = (shapeSetting.dashPattern == null)?null:shapeSetting.dashPattern.clone();
		return ls;
	}

	public ShapeFormat getSetting(ShapeFormat ss) {
		ss.lineColor = shapeSetting.lineColor;
		ss.lineSize = shapeSetting.lineSize;
		ss.dashPattern = (shapeSetting.dashPattern == null)?null:shapeSetting.dashPattern.clone();
		ss.fillColor = shapeSetting.fillColor;
		ss.corner = shapeSetting.corner;
		return ss;
	}

	public void setSetting(LineFormat ls) {
		shapeSetting.lineColor = ls.lineColor;
		shapeSetting.lineSize = ls.lineSize;
		shapeSetting.dashPattern = (ls.dashPattern==null)?null:ls.dashPattern.clone();
		updateLineSetting();
	}

	public void setSetting(ShapeFormat ss) {
		shapeSetting.lineColor = ss.lineColor;
		shapeSetting.lineSize = ss.lineSize;
		shapeSetting.dashPattern = (ss.dashPattern==null)?null:ss.dashPattern.clone();
		shapeSetting.fillColor = ss.fillColor;
		shapeSetting.corner = ss.corner;
		updateShapeSetting();
	}

	private void updateDashField() {
		if (shapeSetting.dashPattern == null) {
			lineTypeTF.setText("");
			return;
		}
		String s = "";
		for (float f : shapeSetting.dashPattern) {
			s += formatter.format(f);
			s += ";";
		}
		lineTypeTF.setText(s.substring(0, s.length() - 1));
	}

	private void updateLineSetting() {
		if(lineColorB == null)
			return;
		lineColorIcon.color = shapeSetting.lineColor;
		lineColorB.repaint();
		lineSizeTF.setValue(shapeSetting.lineSize);
		updateDashField();
		previewPanel.repaint();
	}

	private void updateShapeSetting() {
		updateLineSetting();
		fillColorIcon.color = shapeSetting.fillColor;
		fillColorB.repaint();
		if (cornerTF != null)
			cornerTF.setValue(shapeSetting.corner);
		previewPanel.repaint();
	}
	
	private void toggleListener(Object arg) {
		for(SettingListener s: listenerList) {
			s.settingChanged(arg);
		}
	}
	
	ArrayList<SettingListener> listenerList = new ArrayList<SettingListener>();
	public void addSettingListener(SettingListener sl) {
		listenerList.add(sl);
	}
	public void removeSettingListener(SettingListener sl) {
		listenerList.remove(sl);
	}
	public void clearSettingListener() {
		listenerList.clear();
	}
}